package com.example.demo.nio;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class Channel {
    public static void main(String[] args) throws IOException {
        // 老方式
        tradition();
        // 更好的方式
        modern();
    }


    public static void tradition() throws IOException {
        // 随机访问流
        RandomAccessFile randomAccessFile1 = new RandomAccessFile("1.txt", "rw");
        RandomAccessFile randomAccessFile2 = new RandomAccessFile("2.txt", "rw");
        // 文件操作Channel
        FileChannel channel1 = randomAccessFile1.getChannel();
        FileChannel channel2 = randomAccessFile2.getChannel();
        // 数据缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(8);
        Charset charset = StandardCharsets.UTF_8; // 指定字符编码为 UTF-8

        // 这个方法可以直接设置指针的开始位置
        // 结束位置可以通过设置ByteBuffer的长度来实现
        channel1.position(2);

        int len =0;
        while((len= channel1.read(buffer))!=-1){
            // 反转操作指针,因为在上一句read中是从通道往buffer中写入了数据,那么现在数据指针就指向了写入数据的末尾
            // 这个方法就会让指针指向开头,并且让大小限制指针指向写入时标记的末尾
            buffer.flip();
            // 如果要写入其他文件,则直接可以在这里将buffer用通道全部写入进去
            channel2.write(buffer);
            // 注意如果你写入了其他文件，则指针会去你操作的最后一个位置,所以记得再次反转指针
            buffer.flip();
            // 实际不要这样，粗暴的拆分字节会导致乱码或下标越界，这里只是方便演示
            int p =buffer.remaining()/2;
            // 判断操作范围内(就是当前两个指针的范围内)是否有剩余元素未处理
            while(buffer.hasRemaining()){
                // 根据remaining获取的当前操作范围内的元素数量(就是字节长度)
                byte[] b = new byte[p];
                // 读取对应的元素数量
                buffer.get(b);
                // 这里只是一个演示，用来输出，不用太管
                if(buffer.remaining()==p){
                    System.out.print(new String(b,charset)+"=======分隔一下=======");
                }else{
                    System.out.print(new String(b,charset));
                }
            }
            buffer.clear();
        }
        // 记得关闭资源
        randomAccessFile1.close();
        randomAccessFile2.close();
        channel1.close();
        channel2.close();
    }

    public static void modern() throws IOException {

        RandomAccessFile randomAccessFile1 = new RandomAccessFile("3.txt", "rw");
        RandomAccessFile randomAccessFile2 = new RandomAccessFile("4.txt", "rw");
        FileChannel fileChannel1=randomAccessFile1.getChannel();
        FileChannel fileChannel2=randomAccessFile2.getChannel();

        // 直接通过这个方法，给上开始和结束的字节范围和要传的目的地Channel即可直接写入
        fileChannel1.transferTo(0,fileChannel1.size(),fileChannel2);

        // 记得关闭资源
        randomAccessFile1.close();
        randomAccessFile2.close();
        fileChannel1.close();
        fileChannel2.close();

    }


}
